package com.vhall.component.framework.common.utils;

import com.vhall.component.framework.common.exception.BusinessException;
import org.apache.commons.lang3.time.DateUtils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;

public class DateTimeUtils extends DateUtils {

    /**
     * 将 Date 转换成LocalDate * atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
     */
    public static LocalDate dateToLocalDate(Date date) {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDate();
    }

    /**
     * 将 Date 转换成LocalDateTime * atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDateTime();
    }

    /**
     * 将LocalDate 转换成 Date
     */
    public static Date localDateToDate(LocalDate localDate) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDate.atStartOfDay(zoneId);
        return Date.from(zdt.toInstant());
    }

    /**
     * 将LocalDateTime 转换成 Date
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        return Date.from(zdt.toInstant());
    }

    /**
     * 将localDate按照一定的格式转换成String
     *
     * @param localDate
     * @param pattern   对LocalDate进行格式化时不能带时分秒信息，否则报错
     * @return
     */
    public static String localDateFormat(LocalDate localDate, String pattern) {
        return localDate.format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 将localDateTime 按照一定的格式转换成String
     */
    public static String localDateTimeFormat(LocalDateTime localDateTime, String pattern) {
        return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 将String 按照pattern 转换成LocalDate
     */
    public static LocalDate localDateParse(String date, String pattern) {
        return LocalDate.parse(date, DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 将String 按照pattern 转换成LocalDateTime
     */
    public static LocalDateTime localDateTimeParse(String time, String pattern) {
        return LocalDateTime.parse(time, DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 将date转换成String
     */
    public static String dateFormat(Date date, String pattern) {
        return localDateTimeFormat(dateToLocalDateTime(date), pattern);
    }

    /**
     * 获取两个日期的差 field参数为ChronoUnit.*
     *
     * @param startTime
     * @param endTime
     * @param field     单位(年月日时分秒)
     * @return
     */
    public static long betweenTwoTime(LocalDateTime startTime, LocalDateTime endTime, ChronoUnit field) {
        Period period = Period.between(LocalDate.from(startTime), LocalDate.from(endTime));
        if (field == ChronoUnit.YEARS) {
            return period.getYears();
        }
        if (field == ChronoUnit.MONTHS) {
            return period.getYears() * 12L + period.getMonths();
        }
        return field.between(startTime, endTime);
    }
    private final static Calendar calendar = Calendar.getInstance();
    /**
     * 将秒数转化为时间字符串 hh:mm:ss
     * @param seconds 秒数
     * @return
     */
    public static String secondToTimeFormatStrHHMMSS(int seconds) {
        if (seconds < 0) {
            throw new BusinessException(20000, "时间不能为负数", "biz.time.cannot.negative ");
        }
        calendar.setTimeInMillis(seconds * 1000L);
        int hour = (seconds / 3600);
        String timeStr = String.format("%02d:%02d:%02d", hour,
                calendar.get(Calendar.MINUTE),
                calendar.get(Calendar.SECOND));
        return timeStr;
    }
    public static void main(String[] args) {
        int seconds = 144514;
        System.out.println(DateTimeUtils.secondToTimeFormatStrHHMMSS(seconds));
        System.out.println(DateTimeUtils.secondToTimeFormatStrHHMMSS(0));
        System.out.println(DateTimeUtils.secondToTimeFormatStrHHMMSS(100));
        System.out.println(DateTimeUtils.secondToTimeFormatStrHHMMSS(1000));
        System.out.println(DateTimeUtils.secondToTimeFormatStrHHMMSS(10000));
        System.out.println(DateTimeUtils.secondToTimeFormatStrHHMMSS(100000));
        System.out.println(DateTimeUtils.secondToTimeFormatStrHHMMSS(1000000));
        System.out.println(DateTimeUtils.secondToTimeFormatStrHHMMSS(10000000));
        System.out.println(DateTimeUtils.secondToTimeFormatStrHHMMSS(-10000000));
    }
}
